package server;

import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.BufferedReader;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.URLDecoder;
import java.util.ArrayList;
import java.util.List;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import learner.ModelLearner;
import learner.Pattern;
import learner.PatternModel;
import learner.PatternReader;
import learner.PatternType;
import learner.hmm.BaumWelchLearner;
import learner.hmm.HMMModel;

import org.eclipse.jetty.server.Request;
import org.eclipse.jetty.server.Server;
import org.eclipse.jetty.server.handler.AbstractHandler;

import classifier.HMMClassifier;
import classifier.DTWClassifier;
import classifier.HMModelReader;

import com.google.gson.Gson;


public class MyHttpHandler extends AbstractHandler implements ActionListener {
	  public static void main(String[] args) throws Exception
	    {
		  	View view = new View();
		  	MyHttpHandler handler = new MyHttpHandler();
		  	view.addListener(handler);
	        Server server = new Server(5000);
	        server.setHandler(handler);
	        server.start();
	        server.join();
	    }
	  
	  public MyHttpHandler()  {
		  
	  }

	  private Pattern pattern = new Pattern();
	@Override
	public void handle(String target, Request baseRequest, HttpServletRequest request,
			HttpServletResponse response) throws IOException, ServletException {
		response.setContentType("text/html;charset=utf-8");
        response.setStatus(HttpServletResponse.SC_OK);
        baseRequest.setHandled(true);
		if (baseRequest.getMethod().equals("POST")){
			pattern = pattern.append(readPattern(baseRequest));
	        DTWClassifier dtwClassifier = new DTWClassifier();
//			response.getWriter().write(classifier.classify(pattern));
//	        List<HMMModel> patternModels = new HMMModelReader().giveModels();
	        List<HMMModel> patternModels = getHMMPatternModels();
			HMMClassifier hmmClassifier = new HMMClassifier(patternModels);
			response.getWriter().write(dtwClassifier.classify(pattern)+ "<br>");
			response.getWriter().write(hmmClassifier.classify(pattern));
		}
		else {	
	        String pattern_walker = readHtmlFile("pattern_walker.html");
	        response.getWriter().write(pattern_walker);
		}
		
	}

	private List<HMMModel> getHMMPatternModels() {
		List<HMMModel> models = new ArrayList<HMMModel>();
		PatternReader reader = new PatternReader();
		for (PatternType patternType : PatternType.values()) {
			List<Pattern> patterns = new ArrayList<Pattern>();
			patterns = reader.givePatterns(patternType.ordinal()+1);
			ModelLearner learner = new BaumWelchLearner();
			HMMModel model = (HMMModel)learner.learnModel(patternType.name(), patterns);
			models.add(model);
		}
		return models;
	}

	private String readHtmlFile(String fileName) {
		StringBuilder builder = new StringBuilder();
		String readLine;
		try {
			BufferedReader reader = new BufferedReader(new FileReader(fileName));
			while ((readLine = reader.readLine()) != null) {
				builder.append(readLine);
				builder.append('\n');
			}
				
			reader.close();
			return builder.toString();
		} catch (FileNotFoundException e) {
			e.printStackTrace();
			return null;
		} catch (IOException e) {
			e.printStackTrace();
			return null;
		}
	}
	
	public Pattern readPattern(Request request){
		InputStream is;
		try {
			is = request.getInputStream();
			BufferedReader reader = new BufferedReader(new InputStreamReader(is));
			String readLine;
			Pattern pattern = null;
			while ((readLine = reader.readLine()) != null) {
				String jsonString = readLine.substring(5);
				jsonString = URLDecoder.decode(jsonString, "UTF-8");
				Gson gson = new Gson();
				pattern = gson.fromJson(jsonString, Pattern.class);
				
			}
			return pattern;
		} catch (IOException e) {
			e.printStackTrace();
			return null;
		}
		
	}

	@Override
	public void actionPerformed(ActionEvent e) {
		pattern = new Pattern();
		
	}
	
}